package cn.zsxmlv.modules.sys.service.impl;

import cn.zsxmlv.common.exception.RRException;
import cn.zsxmlv.common.utils.*;
import cn.zsxmlv.modules.sys.dao.SysUserDao;
import cn.zsxmlv.modules.sys.entity.SysUserEntity;
import cn.zsxmlv.modules.sys.entity.SysUserRoleEntity;
import cn.zsxmlv.modules.sys.oauth2.TokenGenerator;
import cn.zsxmlv.modules.sys.service.SysUserRoleService;
import cn.zsxmlv.modules.sys.service.SysUserService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author: zs
 * @description: 用户管理
 * @date: 2019/1/23 14:47
 */
@Service
@Transactional
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SysUserRoleService sysUserRoleService;

    // 单设备登录
    @Value("${erp.single-devices-login}")
    private boolean singleDeviceLogin;

    @Value("${erp.expire}")
    private int EXPIRE;

    @Override
    public void save(SysUserEntity userEntity) {
        // 1、保存用户
        SysUserEntity entity = this.queryByUsername(userEntity.getUsername());

        if (entity != null) {
            throw new RRException("该用户已存在");
        }
        String salt = UUID.randomUUID().toString();
        userEntity.setSalt(salt);

        String password = new Sha256Hash(userEntity.getPassword(), salt).toHex();
        userEntity.setPassword(password);
        userEntity.setCreateTime(new Date());
        this.save(userEntity);

        // 2、保存用户角色
        List<Integer> roleIdList = userEntity.getRoleIdList();
        if (roleIdList != null && roleIdList.size() > 0) {
            List<SysUserRoleEntity> list = new ArrayList<>();
            for (Integer roleId : roleIdList) {
                SysUserRoleEntity build = SysUserRoleEntity.builder().roleId(roleId).userId(userEntity.getId()).build();
                list.add(build);
            }
            sysUserRoleService.insertBatch(list);
        }
    }

    @Override
    public SysUserEntity queryByUsername(String username) {
        return baseMapper.queryByUserName(username);
    }

    @Override
    public R createToken(int userId) {
        // 过期时间 默认两小时 单位：秒

        String token = TokenGenerator.generateValue();

        String loginUserKey = RedisKeys.getLoginUserKey(userId);

        SysUserEntity userEntity = this.selectById(userId);

        // 单设备登录
        if (singleDeviceLogin) {
            String oldToken = redisUtils.get(loginUserKey);
            if (!StringUtils.isBlank(oldToken)) {
                redisUtils.delete(oldToken);
            }
        }

        // 更新 redis 中的token及user对象信息
        redisUtils.delete(loginUserKey);

        redisUtils.set(loginUserKey, token, EXPIRE);

        redisUtils.set(token, userEntity, EXPIRE);

        return R.ok().put("token", token).put("expire", EXPIRE);
    }

    @Override
    public List<Integer> queryAllMenuId(int userId) {
        return baseMapper.queryAllMenuId(userId);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String username = (String) params.get("username");
        Integer createUserId = (Integer) params.get("createUserId");

        Page<SysUserEntity> page = this.selectPage(new Query<SysUserEntity>(params).getPage(),
                new EntityWrapper<SysUserEntity>()
                        .like(StringUtils.isNotBlank(username), "username", username)
                        .eq(createUserId != null, "create_user_id", createUserId));

        return new PageUtils(page);
    }

}
